<template>
  <el-card shadow="hover" style="width: 350px">
    <template #header>
      <div class="option-header">
        <div class="option-header-content"><span>区间累计期权</span></div>
        <div v-if="props.calcSuccess=='true'" class="option-header-content"><span style="color: #22bb98 ">计算成功</span>
        </div>
        <!--        <div v-if="props.calcSuccess=='false'" class="option-header-content"><span style="color: #e53c3c">计算失败</span></div>-->
        <div v-if="props.calcSuccess=='false'" class="option-header-content">
          <el-tooltip effect="light">
            <template #content>
              <div style="width: 280px;">
                <span style="color: #e53c3c;">{{ props.errorMsg }}</span>
              </div>
            </template>
            <span style="color: #e53c3c">计算失败</span>
          </el-tooltip>
        </div>
        <div>
          <el-button style="background: transparent;" :disabled="cpoyWait" class="delete" v-if="props.useType=='calc'" @click="copy" title="复制">
            <el-icon>
              <copy-document/>
            </el-icon>
          </el-button>
          <el-button style="background: transparent;" class="delete" @click="cancel" title="关闭">
            <el-icon>
              <circle-close/>
            </el-icon>
          </el-button>
        </div>
      </div>
    </template>

    <el-form ref="formRef" :disabled="form.data.readOnly" :model="form.data" label-width="auto" size="small"
             :rules="rules">
      <div class="optionst01">
        <el-form-item label="交易方向" prop="payDirection">
          <el-radio-group v-model="form.data.payDirection" size="small" :fill="getColor()">
            <el-radio-button label="1">买入</el-radio-button>
            <el-radio-button label="-1">卖出</el-radio-button>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="标的" label-width="auto" prop="instrumentId">
          <Underlyer v-model="form.data.instrumentId" @change="onBlurInstrumentId" :underlyerId="form.data.instrumentId" :filterDate="true" ref="underlyerIdRef"/>
        </el-form-item>
        <!--合约乘数-->
        <!--      todo-->
        <el-form-item label="起始日" label-width="auto" prop="effectiveDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.effectiveDate" @blur="onBlurEffectiveDate" type="date" placeholder="">
          </el-date-picker>
        </el-form-item>

        <el-form-item label="期限" label-width="auto" prop="term">
          <Numberinput v-model="form.data.term" maxlength="4" :min="1" append="D"/>
        </el-form-item>

        <el-form-item label="到期日" label-width="auto" prop="terminationDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.terminationDate" type="date" placeholder=""/>
        </el-form-item>


        <el-form-item label="到期支付偏移" label-width="auto" prop="paymentDaysOffset">
          <Numberinput v-model="form.data.paymentDaysOffset" maxlength="4" append="D"/>

        </el-form-item>

        <el-form-item label="到期支付日" label-width="auto" prop="terminationDate">
          <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.terminationPaymentDate"
                          type="date"
                          placeholder=""/>
        </el-form-item>

        <el-form-item label="名义本金" prop="notional">
          <InputAmount v-model:value="form.data.notional" append="元" maxlength="20" format="#,##0.00"></InputAmount>
        </el-form-item>


        <el-form-item label="期初价格" label-width="auto" prop="spotPrice">
          <el-col :span="8">
            <el-checkbox name="status" false-label="0" true-label="1" v-model="form.data.priceOnWait">待定</el-checkbox>
          </el-col>
          <el-col :span="16">
            <InputAmount v-model:value="form.data.spotPrice" @change="() => {proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''}" maxlength="20" :disabled="form.data.priceOnWait=='1'"
                         format="#,##0.##" append="元"/>
          </el-col>
        </el-form-item>

        <el-form-item label="交易数量" prop="optionEntitlement">
          <Numberinput v-model="form.data.optionEntitlement" precision="2" maxlength="20"
                       :disabled="form.data.priceOnWait=='1'" @change="optionEntitlementChange"/>
        </el-form-item>
      </div>
      <!---------------------------------------------- 分割线---------------------------------------------------------->
      <div :class="!form.data.readOnly?'optionst02 optionst02_d':'optionst02'">
        <el-tooltip content="请查看高级设置" placement="top" :disabled="!form.data.singleSectionHidden">
          <el-form-item label="区间下限">
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.floorRate" @blur="onBlurFloorRate"
                           :placeholder="请填写" precision="2" :input-style="Dialog.type=='floorRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="18" append="%"/>
            </el-col>
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.floorPrice" @blur="onBlurFloorPrice"
                           :placeholder="请填写" precision="2" :input-style="Dialog.type=='floorRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="20" append="元"/>
            </el-col>
          </el-form-item>
        </el-tooltip>
        <el-tooltip content="请查看高级设置" placement="top" :disabled="!form.data.singleSectionHidden">
          <el-form-item label="区间上限">
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.capRate" @blur="onBlurCapRate"
                           :placeholder="请填写" precision="2" @change="reloadRowEvent()"
                           :input-style="Dialog.type=='capRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="18" append="%"/>
            </el-col>
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.capPrice" @blur="onBlurCapPrice"
                           :placeholder="请填写" precision="2" @change="reloadRowEvent()"
                           :input-style="Dialog.type=='capRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="20" append="元"/>
            </el-col>
          </el-form-item>
        </el-tooltip>
        <el-tooltip content="请查看高级设置" placement="top" :disabled="!form.data.singleSectionHidden">
          <el-form-item label="区间内收益率">
            <Numberinput v-model=" form.data.singleSection.payOffRate" @change="reloadRowEvent()"
                         :placeholder="请填写" precision="2" maxlength="20"
                         :input-style="Dialog.type=='payOffRate'?'color: red;':''"
                         :disabled="form.data.singleSectionHidden" append="%"/>

<!--            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.payOffRate" @change="reloadRowEvent()"
                           :placeholder="请填写" precision="2" maxlength="20" @blur="onBlurPayOffRate"
                           :input-style="Dialog.type=='payOffRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" append="%"/>
            </el-col>
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.payOffPrice" @blur="onBlurPayOffPrice"
                           :placeholder="请填写" precision="2"
                           :input-style="Dialog.type=='payOffRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="20" append="元"/>
            </el-col>-->
          </el-form-item>
        </el-tooltip>
        <el-tooltip content="请查看高级设置" placement="top" :disabled="!form.data.singleSectionHidden">
          <el-form-item label="区间外收益率">
            <Numberinput v-model="form.data.singleSection.outPayOffRate" @change="reloadRowEvent()"
                         :placeholder="请填写" precision="2" maxlength="20"
                         :input-style="Dialog.type=='outPayOffRate'?'color: red;':''"
                         :disabled="form.data.singleSectionHidden" append="%"/>

<!--            <el-col :span="12">
              <Numberinput v-model="form.data.singleSection.outPayOffRate" @change="reloadRowEvent()"
                                            :placeholder="请填写" precision="2" maxlength="20" @blur="onBlurOutPayOffRate"
                                            :input-style="Dialog.type=='outPayOffRate'?'color: red;':''"
                                            :disabled="form.data.singleSectionHidden" append="%"/>
            </el-col>
            <el-col :span="12">
              <Numberinput v-model=" form.data.singleSection.outPayOffPrice" @blur="onBlurOutPayOffPrice"
                           :placeholder="请填写" precision="2" @change="reloadRowEvent()"
                           :input-style="Dialog.type=='outPayOffRate'?'color: red;':''"
                           :disabled="form.data.singleSectionHidden" maxlength="20" append="元"/>
            </el-col>-->
          </el-form-item>
        </el-tooltip>


        <el-form-item label="计息区间">
          <el-button type="text" @click="dialogVisible = true">高级设置</el-button>
        </el-form-item>
        <el-dialog v-model="dialogVisible" width="50%" :modal-append-to-body="false" draggable
                   :close-on-click-modal="false" :modal='false' :lock-scroll="false" :append-to-body="false"
                   :close-on-press-escape="false">
          <template #title>
            <div style="text-align: left">
              <span>计息区间</span>
            </div>
          </template>
          <vxe-toolbar ref="xToolbar" :loading="rangeDialog.loading" width="50%">
            <template #buttons>
              <el-button type="primary" icon="plus" @click="insertEvent">新增</el-button>
              <el-button type="danger" icon="Delete" content="删除" @click="removeRowEvent">删除</el-button>
              <el-button type="reset" icon="Refresh" @click="reloadRowEvent">重置行权区间</el-button>
            </template>
          </vxe-toolbar>

          <vxe-table
              border
              show-overflow
              keep-source
              ref="xTable"
              height="500"
              width="70%"
              :column-config="{resizable: true}"
              :loading="rangeDialog.loading"
              :data="form.data.sections"
              :edit-rules="rangeDialog.validRules"
              :edit-config="{trigger: 'click', mode: 'row', showUpdateStatus: true, showInsertStatus: true}">
            <vxe-column type="checkbox" width="30"></vxe-column>
            <vxe-column :edit-render="{}" field="floorRate" title="行权价下限(%)" width="130">
              <template #default="{ row }">
                <span>{{ row.floorRate }}</span>
              </template>
              <template #edit="{ row }">
                <Numberinput v-model="row.floorRate" append="%" precision="2"
                             @blur="ProxyLinkRate(row,row.floorRate,form.data.spotPrice,'floorPrice')"/>
<!--                             @blur="row.floorPrice = round(row.floorRate/100*form.data.spotPrice,2)"/>-->
              </template>
            </vxe-column>
            <vxe-column :edit-render="{name: 'input', attrs: {type: 'number'}}" field="floorPrice"
                        title="行权价下限(￥)"
                        width="130">
              <template #default="{ row }">
                <span>{{ row.floorPrice }}</span>
              </template>
              <template #edit="{ row }">
                <InputAmount v-model:value="row.floorPrice" append="元" format="#,##0.00"
                             @blur="ProxyLinkPrice(row,row.floorPrice,form.data.spotPrice,'floorRate')"></InputAmount>
              </template>
            </vxe-column>

            <vxe-column :edit-render="{}" field="capRate" title="行权价上限(%)" width="130">
              <template #default="{ row }">
                <span>{{ row.capRate == max / 100 ? '无穷大' : row.capRate }}</span>
              </template>
              <template #edit="{ row }">
                <Numberinput v-model="row.capRate"
                             @blur="ProxyLinkRate(row,row.capRate,form.data.spotPrice,'capPrice')"
                             precision="2" append="%"/>
              </template>
            </vxe-column>

            <vxe-column :edit-render="{}" field="capPrice" title="行权价上限(￥)" width="130">
              <template #default="{ row }">
                <span>{{ row.capPrice == max ? '无穷大' : row.capPrice }}</span>
              </template>
              <template #edit="{ row }">
                <InputAmount v-model:value="row.capPrice" append="元" format="#,##0.00"
                             @blur="ProxyLinkPrice(row,row.capPrice,form.data.spotPrice,'capRate')"></InputAmount>
              </template>
            </vxe-column>


            <vxe-column :edit-render="{}" field="payOffRate" title="收益率(%)" width="130">
              <template #default="{ row }">
                <span>{{ row.payOffRate }}</span>
              </template>
              <template #edit="{ row }">
                <Numberinput v-model="row.payOffRate" append="%" precision="2"/>
              </template>
            </vxe-column>
            <vxe-column field="isIncludeCap" title="包含上限" :edit-render="{}">
              <template #default="{ row }">
                <span>{{ row.isIncludeCap == 1 ? '包含' : '不包含' }}</span>
              </template>
              <template #edit="{ row }">
                <el-switch
                    v-model="row.isIncludeCap"
                    :active-icon="Check"
                    :inactive-icon="Close"
                    active-value="1"
                    inactive-value="0"/>
              </template>
            </vxe-column>

            <vxe-column field="isIncludeFloor" title="包含下限" :edit-render="{}">
              <template #default="{ row }">
                <span>{{ row.isIncludeFloor == 1 ? '包含' : '不包含' }}</span>
              </template>
              <template #edit="{ row }">
                <el-switch
                    v-model="row.isIncludeFloor"
                    :active-icon="Check"
                    :inactive-icon="Close"
                    active-value="1"
                    inactive-value="0"
                />
                <!--                <el-input v-model="row.isIncludeFloor" type="checkbox"></el-input>-->
              </template>
            </vxe-column>
          </vxe-table>
          <template #footer>
            <div class="dialog-footer">
              <el-button type="primary" @click="calcInvert" v-show="props.useType=='calc'||props.useType=='scene'"
                         :disabled="form.data.priceOnWait=='1'">反算
              </el-button>
              <el-button @click="saveEvent">确 定</el-button>
              <!--              <el-button type="primary" @click="dialogVisible = false">确 定</el-button>-->
              <el-button @click="dialogVisible = false">取 消</el-button>
            </div>
          </template>
        </el-dialog>
        <el-form-item label="观察日期">
          <el-button type="text" @click="openObservation">观察日期</el-button>
        </el-form-item>
        <!--        观察日管理-->
        <el-dialog title="观察日管理" v-model="ObservationVisible" width="40%" append-to-body modal-append-to-body="false">
          <div>
            <el-row>
              <el-col :span="12">
                <el-form-item label="观察开始日">
                  <el-row>
                    <el-col :span="12">
                      <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.startDate"
                                      type="date" :disabled-date="disabledDate"
                                      placeholder=""/>
                    </el-col>
                    <el-col :span="12">
                      <dictCombox v-model="form.data.isIncludeStartDate"
                                  dictType="include"
                                  :style="{width: '100%'}"></dictCombox>
                    </el-col>
                  </el-row>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="观察频率">
                  <dictCombox :span="12" v-model="form.data.frequency" disabled="false"
                              dictType="ObserFrequency"
                              :style="{width: '100%'}"></dictCombox>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row>
              <el-col :span="12">
                <el-form-item label="观察结束日">
                  <el-col :span="12">
                    <el-date-picker value-format="YYYY-MM-DD" v-model="form.data.endDate"
                                    type="date" :disabled-date="disabledDate"
                                    placeholder=""/>
                  </el-col>
                  <el-col :span="12">
                    <dictCombox :span="12" v-model="form.data.isIncludeEndDate"
                                dictType="include"
                                :style="{width: '100%'}"></dictCombox>
                  </el-col>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="交易日历">
                  <dictCombox :span="12" v-model="form.data.calendar"
                              dictType="tradeCalendar"
                              :style="{width: '100%'}"></dictCombox>
                </el-form-item>
              </el-col>
            </el-row>
            <!--            <el-row style="margin-top: 16px;text-align: center; display: inline-block">
                          <el-col :span="11" style="margin: 5px 5px 5px 25px">
                            <el-table :data="getLeftDates()" style="width: 100%" height="169" border>
                              <el-table-column type="index" label="序号"/>
                              <el-table-column label="全部交易日" width="180">
                                <template #default="scope">
                                  <div style="display: flex; align-items: center">
                                    <el-icon>
                                      <timer/>
                                    </el-icon>
                                    <span style="margin-left: 10px">{{ scope.row.date }}</span>
                                  </div>
                                </template>
                              </el-table-column>
                              <el-table-column label="添加">
                                <template #default="scope">
                                  <el-button circle size="small" icon="plus" @click="handleEdit(scope.$index, scope.row)"/>
                                </template>
                              </el-table-column>
                            </el-table>
                          </el-col>
                          <el-col :span="11" style="margin: 5px 5px 5px 20px">
                            <el-table :data="getRightDates()" style="width: 100%" height="169" border>
                              <el-table-column type="index" label="序号"/>
                              <el-table-column label="观察日序列" width="180">
                                <template #default="scope">
                                  <div style="display: flex; align-items: center">
                                    <el-icon>
                                      <timer/>
                                    </el-icon>
                                    <span style="margin-left: 10px">{{ scope.row.date }}</span>
                                  </div>
                                </template>
                              </el-table-column>
                              <el-table-column label="删除">
                                <template #default="scope">
                                  <el-button circle
                                             size="small"
                                             @click="handleDelete(scope.$index, scope.row)"
                                  >
                                    <el-icon>
                                      <minus/>
                                    </el-icon>
                                  </el-button>
                                </template>
                              </el-table-column>
                            </el-table>
                          </el-col>
                          <el-col :span="2" style="width: 80px;float: left;padding-top: 50px;">
                            <el-button type="primary" style="margin: 8px 0 0 2px;" @click="EditCalendars('l')">清空序列</el-button>
                            <el-button type="primary" style="margin: 8px 0 0 2px;" @click="EditCalendars('r')">添加全部</el-button>
                          </el-col>
                        </el-row>-->

          </div>
          <template #footer>
            <div class="dialog-footer">
              <el-button @click="saveObservations">确 定</el-button>
              <el-button @click="ObservationVisible = false">取 消</el-button>
            </div>
          </template>
        </el-dialog>

        <el-form-item label="是否年化">
          <dictCombox v-model="form.data.moneynessOption"
                      dictType="boolType"
                      :style="{width: '100%'}"></dictCombox>
        </el-form-item>
<!--        <el-form-item label="计息天数"  v-show="form.data.moneynessOption>0" prop="daycounterTerm">
          <Numberinput v-model="form.data.term" precision="2" append="D"/>
        </el-form-item>-->

        <el-form-item label="计息基准" v-show="form.data.moneynessOption>0" prop="daycounter">
          <dictCombox v-model="form.data.daycounter" prop='disDayCount'
                      dictType="dayCounter"
                      :style="{width: '100%'}"></dictCombox>
        </el-form-item>

        <el-form-item class="operation">
          <el-button type="primary" @click="calc" :disabled="form.data.priceOnWait=='1'">计算</el-button>
          <el-button type="primary" @click="calcInvert" v-show="props.useType=='calc'||props.useType=='scene'"
                     :disabled="form.data.priceOnWait=='1'">反算
          </el-button>
          <el-button @click="save2CalcLog" v-show="props.useType=='calc'" :disabled="form.data.priceOnWait=='1'">存为草稿
          </el-button>
        </el-form-item>
      </div>
    </el-form>
    <div class="optionst03">
      <PricingParam ref="PricingParamRef" :formData="form.data"  :valueDate="props.valueDate"  :index="props.index"
                    label-width="auto" :filterList="form.data.filterList" :disabled="form.data.readOnly"
                    :productType="productType" size="small"
                    :calcPricingParam="props.calcPricingParam"></PricingParam>
    </div>
    <div v-show="props.useType!='scene'">
      <singleResult ref="resultCompRef" :result="form.result" :index="props.index"  :form="form"
                    :calcInvert="props.useType=='calc'"></singleResult>
    </div>
  </el-card>
  <el-dialog
      v-model="calcInvertVisible"
      title="反算结果"
      width="20%"
      destroy-on-close
      center
  >
    <el-form ref="DialogForm" disabled :model="Dialog.data" label-width="auto" size="small">
      <el-form-item v-if="Dialog.showMoneynessOption" :label="Dialog.data.labelPercentage">
        <el-col :span="8">
          <el-checkbox v-model="Dialog.data.moneynessOption" name="status" false-label="0" true-label="1">年化
          </el-checkbox>
        </el-col>
        <el-col :span="16">
          <Numberinput v-model="Dialog.data.valuePercentage" maxlength="18" precision="2" append="%"/>
        </el-col>
      </el-form-item>
      <el-form-item v-if="!Dialog.showMoneynessOption" :label="Dialog.data.labelPercentage">
        <Numberinput v-model="Dialog.data.valuePercentage" maxlength="18" precision="2" append="%"/>
      </el-form-item>
      <el-form-item :label="Dialog.data.labelAmount">
        <Numberinput v-model="Dialog.data.valueAmount" maxlength="18" precision="2" append="元"/>
      </el-form-item>
    </el-form>
  </el-dialog>
</template>

<script setup>
import {
  getCurrentInstance,
  onMounted,
  reactive,
  ref,
  toRefs,
  watch,
  nextTick
} from 'vue'
import Underlyer from '../../../../xquant/base/underlyer'
import Numberinput from '../../../../xquant/base/number'
import InputAmount from '../../../../xquant/base/InputAmount'
import dictCombox from '@/xquant/base/dictCombox'
import PricingParam from '@/views/calc/otcOtion/pricingparam/index'
import singleResult from '@/views/calc/otcOtion/result/single'
import {getTradeDay} from '@/utils/calc'
import {isVoid, isNotVoid,calcAnnualizedByTerminationPaymentDate} from '@/utils/util'
import {getTerminationPaymentDate} from '@/api/calc/otcOption/calc'
import {VXETable} from 'vxe-table'
import {Timer} from '@element-plus/icons-vue'
import {getCalendar} from '@/api/calc/otcOption/calc'
import {getOffset, calcContractParamProxy} from '../../../../api/calc/otcOption/calc'
import {formartFormP4, formartTableP2, unFormartNumber, formartFormP2, numberPrecision} from '@/utils/numberUtil'
import {debounce} from 'lodash'
import {setCommonSpotPrice} from '@/views/calc/otcOtion/instrument/common/common'
import {computeType} from "./common/data";
import * as Util from "../../../../utils/util";
import {validateDates} from "./common/validate";
import {
  linkPercentage,
  linkPercentageSource,
  linkPrice,
  linkPriceSource
} from "@/views/calc/otcOtion/instrument/common/formula";
const getColor = () => {
  return form.data.payDirection == '1' ? '#E53C3C' : '#22BB98'
}
const cpoyWait = ref(false)
const {proxy} = getCurrentInstance()
const round = proxy.lsh.round
const productType = 'RangeAccrual'
const form = reactive({
  data: {
    productType: 'RangeAccrual',
    payDirection: '1',
    instrumentId: null,
    effectiveDate: proxy.$moment(new Date()).format('YYYY-MM-DD'),
    terminationDate: '',
    terminationPaymentDate: '',
    term: '30',
    paymentDaysOffset: '0',
    priceOnWait: '0',
    spotPrice: '',
    notional: '',
    optionEntitlement: '',
    moneynessOption: '1',
    daycounter: 'Actual/365',
    calendar: 'CHINA_EX',
    daycounterTerm: '365',
    isIncludeEndDate: '1',
    endDate: '',
    isIncludeStartDate: '1',
    startDate: '',
    frequency: '1D',
    singleSection: {
      capRate: '',
      capPrice: '',
      isIncludeCap: '',
      floorRate: '',
      floorPrice: '',
      isIncludeFloor: '',
      payOffRate: '',
      outPayOffRate: '',
      payOffPrice: '',
      outPayOffPrice: ''
    },
    singleSectionHidden: false,
    sections: [],/*区间*/
    discreteDates: []
  },
  result: {},
  initFlag: ''
})
const calcInvertVisible = ref(false)
const Dialog = reactive({
  showMoneynessOption: true,
  type: '',
  data: {
    valueAmount: '',
    labelAmount: '',
    valuePercentage: '',
    labelPercentage: '',
    moneynessOption: ''
  }
})
watch(() => props.result, (nv, ov) => {
  let other = {
    'type': '区间累计',
    '标的': computed(() => {
      if (proxy.$refs.underlyerIdRef && proxy.$refs.underlyerIdRef.underlyerIdsList[0]) {
        return (proxy.$refs.underlyerIdRef.underlyerIdsList[0].productName + '').trim().split(' ').join(',')
      }
    }),
    '交易日期': props.valueDate,
    '合约交易方向': form.data.payDirection == '1' ? '客户卖价' : '客户买价',
    '合约类型': form.data.optionType == 'Call' ? 'C' : 'P',
    '到期日': form.data.terminationDate,
    '执行价上限': formartFormP2(form.data.singleSection.capPrice),
    '执行价下限': formartFormP2(form.data.singleSection.floorPrice),
    '数量': formartFormP2(form.data.optionEntitlement),
    '名义金额': formartFormP2(form.data.notional),
    '开仓标的价': formartFormP2(form.data.spotPrice),
    '区间内收益率': formartFormP2(form.data.singleSection.payOffRate),
    '区间外收益率': formartFormP2(form.data.singleSection.outPayOffRate),
    '期权单价': computed(() => {
      if (nv.npv) {
        return formartFormP2(nv.npv / form.data.optionEntitlement)
      }
    }),
    '百分比估值': computed(() => {
      if (nv.npv) {
        return formartFormP2(100 * nv.npv / form.data.notional)
      }
    })
  }
  form.result = Object.assign(other, nv)
}, {immediate: true})

// 计息区间 高级设置中的联动逻辑
const ProxyLinkPrice = (obj,divisor,baseNum,path) => {
  if (form.data.priceOnWait != 0) return
  linkPriceSource(obj,divisor,baseNum,path)

}
const ProxyLinkRate = (obj,divisor,baseNum,path) => {
  if (form.data.priceOnWait != 0) return
  linkPercentageSource(obj,divisor,baseNum,path)
}
const onBlurCapRate = () => {
  linkPercentage(form,form.data.singleSection.capRate,form.data.spotPrice,'data.singleSection.capPrice')
}
const onBlurFloorRate = () => {
  linkPercentage(form,form.data.singleSection.floorRate,form.data.spotPrice,'data.singleSection.floorPrice')
}

const onBlurCapPrice = () => {
  linkPrice(form,form.data.singleSection.capPrice,form.data.spotPrice,'data.singleSection.capRate')
}

const onBlurFloorPrice = () => {
  linkPrice(form,form.data.singleSection.floorPrice,form.data.spotPrice,'data.singleSection.floorRate')
}

const defaultSections = reactive({
  data: []
})
const max = Number.MAX_SAFE_INTEGER
defaultSections.data = computed(() => [
  {
    capPrice: form.data.singleSection.floorPrice,
    capRate: form.data.singleSection.floorRate,
    isIncludeCap: '0',
    floorPrice: '',
    floorRate: '',
    isIncludeFloor: '0',
    payOffRate: form.data.singleSection.outPayOffRate,
  },
  {
    capPrice: form.data.singleSection.capPrice,
    capRate: form.data.singleSection.capRate,
    isIncludeCap: '0',
    floorPrice: form.data.singleSection.floorPrice,
    floorRate: form.data.singleSection.floorRate,
    isIncludeFloor: '0',
    payOffRate: form.data.singleSection.payOffRate,
  },
  {
    capPrice: '',
    capRate: '',
    isIncludeCap: '0',
    floorPrice: form.data.singleSection.capPrice,
    floorRate: form.data.singleSection.capRate,
    isIncludeFloor: '0',
    payOffRate: form.data.singleSection.outPayOffRate,
  }])

watch(() => defaultSections.data, () => {
  reloadRowEvent()
})
const dialogVisible = ref(false)
const ObservationVisible = ref(false)
const rules = {
  payDirection: [{required: true, message: '请选择交易方向', trigger: 'change'}],
  instrumentId: [{required: true, message: ' ', trigger: 'change'}],
  effectiveDate: [{required: true, message: ' ', trigger: 'change'}],
  terminationDate: [{required: true, message: ' ', trigger: 'change'}],
  term: [{required: true, message: ' ', trigger: 'change'}],
  paymentDaysOffset: [{required: true, message: ' ', trigger: 'change'}],
  notional: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  daycounter: [{required: true, message: ' ', trigger: 'change'}],
  daycounterTerm: [{required: true, message: ' ', trigger: 'change'}],
  spotPrice: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1') {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  optionEntitlement: [{required: true, message: ' ', trigger: 'change'}, {
    validator: (rule, value, callback) => {
      if (form.data.priceOnWait == '1') {
        return true
      }
      return Number(value) > 0
    }, message: ' ', trigger: 'change'
  }],
  paymentAmountPecentage: [{required: true, message: ' ', trigger: 'change'}],
  paymentAmount: [{required: true, message: ' ', trigger: 'change'}],
}
watch(() => form.data.priceOnWait, (nv, ov) => {
  if (nv == '1') {
    form.data.spotPrice = 0
  } else {
    setSpotPrice()
  }
  setTimeout(()=>{
    onBlurFloorRate()
    onBlurCapRate()
  },100)
})

watch(() => proxy.$attrs.disabled, (nv) => {
  form.data.readOnly = nv
}, {
  immediate: true
})
/*
* 修改状态  false:当前没有操作  true:当前在被其他方法操作
* */
const lock = reactive({
  paymentDaysOffset: false,
  terminationPaymentDate: false,
})
watch(() => form.data.paymentDaysOffset, (nv, ov) => {
  if (nv === '') return
  if (lock.terminationPaymentDate) return
  lock.terminationPaymentDate = true
  onpaymentDaysOffsetChange()
})
const onpaymentDaysOffsetChange = debounce(function () {
  getTerminationPaymentDate({
    'calDay': form.data.terminationDate,
    'offset': form.data.paymentDaysOffset
  }).then(response => {
    lock.terminationPaymentDate = false
    if (response.errorCode != 0) {

    } else {
      form.data.terminationPaymentDate = response.result.CAL_DAY

    }
  })
}, 1000)
watch(() => form.data.terminationPaymentDate, (nv, ov) => {
  if (nv == ov || nv === '') return
  if (lock.paymentDaysOffset) return
  lock.paymentDaysOffset = true
  onterminationPaymentDate()
})
const onterminationPaymentDate = debounce(function (nv, ov) {
  getOffset({
    'day': form.data.terminationPaymentDate,
    'calDay': form.data.terminationDate
  }).then(response => {
    if (response.errorCode != 0) {

    } else {
      if (response.result == null) {
        onpaymentDaysOffsetChange()
        return
      }
      form.data.paymentDaysOffset = response.result.i
      lock.paymentDaysOffset = false
    }
  })
}, 1000)
onUnmounted(() => {
  // 移除组件时，取消定时器
  onpaymentDaysOffsetChange.cancel()
  onterminationPaymentDate.cancel()
})
const onBlurTerminationDate = (nv, ov) => {
  let a = proxy.$moment(form.data.terminationDate)
  let b = proxy.$moment(form.data.terminationPaymentDate)
  form.data.paymentDaysOffset = b.diff(a, 'days')
}
watch(() => [form.data.effectiveDate, form.data.terminationDate], ([nv, n2v], [ov, o2v]) => {
  if (!proxy.lsh.isEmpty(nv) && !proxy.lsh.isEmpty(n2v)) {
    let a = proxy.$moment(n2v)
    let b = proxy.$moment(nv)
    form.data.term = Number(a.diff(b, 'days'))
    form.data.startDate = nv
    form.data.endDate = n2v
  }
  generateData()
})
watch(() => [form.data.term], ([newValue], [oldValue]) => {
  if (isNotVoid(String(form.data.effectiveDate)) && isNotVoid(String(newValue))) {
    let a = proxy.$moment(form.data.effectiveDate)
    form.data.terminationDate = a.add(newValue, 'days').format('YYYY-MM-DD')
    onpaymentDaysOffsetChange()
  }
})
watch(() => [form.data.notional, form.data.spotPrice], ([nv, n2v], [ov, o2v]) => {
  if (!proxy.lsh.isEmpty(nv) && !proxy.lsh.isEmpty(n2v)) {

    form.data.optionEntitlement = String(Number(nv) / Number(n2v))
  }
  //  区间内收益
  if (isVoid(form.data.payOffPrice)){
    onBlurPayOffRate()
  }
  //  区间外收益
  if (isVoid(form.data.outPayOffPrice)){
    onBlurOutPayOffRate()
  }
})
watch(() => [form.data.notional], ([newValue], [oldValue]) => {
  if (optionEntitlementLinkValid(newValue, form.data.spotPrice, form.data.optionEntitlement)) {
    return
  }
  if (isNotVoid(String(newValue))) {
    if (isNotVoid(String(form.data.spotPrice))) {
      form.data.optionEntitlement = proxy.lsh.divide(newValue, form.data.spotPrice).toFixed(4)
      return
    }
    if (isNotVoid(String(form.data.optionEntitlement))) {
      form.data.spotPrice = proxy.lsh.divide(newValue, form.data.optionEntitlement).toFixed(4)
      return
    }
  }
})

const onBlurEffectiveDate = () => {
  form.initFlag = false
  setSpotPrice()
}

watch(() => [form.data.spotPrice], ([newValue], [oldValue]) => {
  if (isNotVoid(String(newValue))) {
    if (isNotVoid(String(form.data.singleSection.floorPrice))) {
      if (form.data.priceOnWait == '1') return
       onBlurFloorPrice()
    }else {
      if (isNotVoid(String(form.data.singleSection.floorRate))) {
        if (form.data.priceOnWait == '1') return
        onBlurFloorRate()
      }
    }



    if (isNotVoid(String(form.data.singleSection.capPrice))) {
      if (form.data.priceOnWait == '1') return
      onBlurCapPrice()
    }else {
      if (isNotVoid(String(form.data.singleSection.capRate))) {
        if (form.data.priceOnWait == '1') return
        onBlurCapRate()
      }
    }
    form.data.sections.forEach(item=>{
      if (isNotVoid(item.capPrice)){
        ProxyLinkPrice(item,item.capPrice,form.data.spotPrice,'capRate')
      }else {
        ProxyLinkRate(item,item.capRate,form.data.spotPrice,'capPrice')
      }
      if (isNotVoid(item.floorPrice)){
        ProxyLinkPrice(item,item.floorPrice,form.data.spotPrice,'floorRate')
      }else {
        ProxyLinkRate(item,item.floorRate,form.data.spotPrice,'floorPrice')
      }
    })



  }
  if (optionEntitlementLinkValid(form.data.notional, newValue, form.data.optionEntitlement)) {
    return
  }

  if (isNotVoid(String(newValue))) {
    if (isNotVoid(String(form.data.notional))) {
      if(newValue == 0){
        form.data.optionEntitlement = 0
      }else {
        form.data.optionEntitlement = proxy.lsh.divide(form.data.notional, newValue).toFixed(4)
      }
      return
    }
    if (isNotVoid(String(form.data.optionEntitlement))) {
      form.data.notional = proxy.lsh.multiply(form.data.optionEntitlement, newValue).toFixed(4)
      return
    }
  }
})
const optionEntitlementChange = (newValue) => {
  if (form.data.priceOnWait == '1') return
  if (optionEntitlementLinkValid(form.data.notional, form.data.spotPrice, newValue)) {
    return
  }
  if (isNotVoid(String(newValue))) {
    if (isNotVoid(String(form.data.spotPrice))) {
      form.data.notional = proxy.lsh.multiply(newValue, form.data.spotPrice).toFixed(0)
      return
    }
    if (isNotVoid(String(form.data.notional))) {
      form.data.spotPrice = proxy.lsh.divide(form.data.notional, newValue).toFixed(4)
      return
    }
  }
}

function optionEntitlementLinkValid(notional, spotPrice, optionEntitlement) {
  if (isNotVoid(String(notional)) && isNotVoid((String(spotPrice))) && isNotVoid(String(optionEntitlement))) {
    if (proxy.lsh.isEqual(optionEntitlement, proxy.lsh.divide(notional, spotPrice).toFixed(4))) {
      return true
    } else {
      return false
    }
  }
}

watch(() => [props.cfgId,form.data.instrumentId], ([newId, oldId]) => {
  getPricingCfg()
  setTimeout(() => {
    proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }, 1000);
})

const onBlurInstrumentId = () => {
  setSpotPrice()
  getPricingCfg()
  setTimeout(() => {
    proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }, 1000);
}
watch(() => props.valueDate, (newValue, oldValue) => {
  if (newValue != oldValue) {
    setSpotPrice()
    //触发修改定价参数的价格
    proxy.$refs.PricingParamRef.setSpotPrice({
      valueDate: props.valueDate,
      instrumentId: form.data.instrumentId
    })
   proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
  }
})
const setSpotPrice = () => {
  setCommonSpotPrice(proxy, form, props)
}
const props = defineProps({
  /*是否为重放*/
  isReCalc: {
    type: Boolean,
    default: false
  },
  calcSuccess: {
    type: String,
    default: ''
  },
  errorMsg: {
    type: String,
    default: ''
  },
  index: {
    type: String,
    default: ''
  },
  useType: {
    type: String,
    default: 'calc'
  },
  del: {
    type: Function,
    default: null
  },
  copy: {
    type: Function,
    default: null
  },
  calc: {
    type: Function,
    default: null
  },
  getDefaultCfg: {
    type: Function,
    default: null
  },
  calcPricingParam: {
    type: Object,
    default: {}
  },
  result: {
    type: Object,
    default: {}
  },
  setformData: {
    type: Function,
    default: null
  },
  formData: {
    type: Object,
    default: null
  },
  save2Trade: {type: Function, default: null},
  save2CalcLog: {type: Function, default: null},
  cfgId: {type: String, default: ''},
  valueDate: {type: String, default: ''}
})
const getResult = () => {
  var data = []
  for (var item in props.result) {
    if (['npv', 'delta', 'gamma', 'vega', 'theta', 'rho', 'spotPrice', 'dscRate'].includes(item)) {
      data.push({
        key: item,
        val: proxy.lsh.ceil(props.result[item], 4)
      })
    }
  }
  return data
}
//定价参数
const getPricingCfg = async () => {
  let query = {
    'calcPricingParam': {
      'cfgId': props.cfgId
    },
    'instrument': {
      'productType': 'RangeAccrual',
      'termsheet': {
        'underlyerIds': [form.data.instrumentId],
        'customLegs': [{
          'legId': 'leg01',
          'productType': 'RangeAccrual'
        }
        ],
        'legs': [{
          'legId': 'leg01',
          'payDirection': '1'
        }
        ]
      }
    }
  }
  //设置定价参数中的定盘价
  proxy.$refs.PricingParamRef.setSpotPrice({
    valueDate:props.valueDate,
    instrumentId:form.data.instrumentId
  })
  if (props.getDefaultCfg != null) {
    props.getDefaultCfg(query, props.index)
  }
}
const cancel = () => {
  props.del(props.index)
}
const copy = () => {
  props.copy(props.index)
  cpoyWait.value = true;
  setTimeout(() => {
    cpoyWait.value = false;
  }, 1000);
}

function convertJson() {
  let sectionsCopy = proxy.lsh.cloneDeep(form.data.sections)
  let calcPriceParam = getCalcPriceParam()
  let otcOption = {
    instrument: {
      'termsheet': {
        'notional': form.data.notional,
        'notionalCurrency': 'CNY',
        'settlementType': 'C',
        'settlementCurrency': 'CNY',
        'effectiveDate': form.data.effectiveDate,
        'effectiveDateConv': 'Following',
        'terminationDate': form.data.terminationDate,
        'terminationDateConv': 'Following',
        'terminationDateCalendar': form.data.calendar,
        'underlyerIds': [
          form.data.instrumentId
        ],
        'calendars': [
          form.data.calendar
        ],
        'legs': [
          {
            'legId': 'leg01',
            'payDirection': form.data.payDirection
          }
        ],
        'customLegs': [
          {
            'legId': 'leg01',
            'productType': 'RangeAccrual',
            periodOfAccrualInterestAdjust: '0',
            'underlyers': [
              {
                'instrumentId': form.data.instrumentId,
                'quoteType': '',
                'spotPrice': form.data.spotPrice,
                'basketWeight': '1',
                'fixingDate': '',
                'fixingDateConv': 'Preceding',
                'fixingDateCalendar': form.data.calendar
              }
            ],
            'observeDates': {
              'startDate': form.data.startDate,
              'startDateConv': 'FOLLOWING',
              'isIncludeStartDate': form.data.isIncludeStartDate,
              'endDate': form.data.endDate,
              'endDateConv': 'FOLLOWING',
              'isIncludeEndDate': form.data.isIncludeEndDate,
              'calendar': form.data.calendar,
              'frequency': form.data.frequency,
              'discreteDates': form.data.discreteDates,
              'discreteDatesConv': ''
            },
            // 'priceRanges': form.data.sections.length > 0 ? form.data.sections : defaultSections.data,
            'priceRanges': sectionsCopy.map(item => {
              return {
                "payoffRate": item.payOffRate / 100,
                "floorPrice": Boolean(item.floorPrice) ? item.floorPrice : '0',
                "floorPriceRate": Boolean(item.floorRate) ? item.floorRate / 100 : '0',
                "capPrice": Boolean(item.capPrice) ? item.capPrice : max,
                "capPriceRate": Boolean(item.capRate) ? item.capRate / 100 : '0',
              }
            }),
            'yearFraction': form.data.moneynessOption == '1' ? calcAnnualizedByTerminationPaymentDate(form.data) : '',//年化天数
            'fixingRounding': '',
            'numberOfOptions': '1',
            'optionEntitlement': form.data.optionEntitlement,
            'moneynessOption': form.data.moneynessOption,
            'daycounter': form.data.moneynessOption == '1' ? form.data.daycounter : '',
            'settlementDateConv': 'Following',
            'settlementDateCalendar': form.data.calendar,
            'settlementDateOffset': form.data.paymentDaysOffset + 'D',
          }
        ],
        'term': form.data.term,

      },
      'productType': 'RangeAccrual'
    },
    calcPricingParam: {
      valueDate: props.valueDate,
      cfgId: props.cfgId,
      calcPPCode: calcPriceParam.calcPPCode,
      underlyingPricingParams: [
        {
          underlyingID: form.data.instrumentId,
          dividend: calcPriceParam.dividend,
          volSurface: calcPriceParam.volSurface,
          funding: calcPriceParam.discount,
          spotPrice: calcPriceParam.spotPrice == '0' ? '' : calcPriceParam.spotPrice,
          spotQuoteType: calcPriceParam.spotQuoteType
        }
      ],
      discount: calcPriceParam.discount,
      'customPricingParam': {}
    },
    underlyingMarkets: [
      {
        'underlyingID': form.data.instrumentId,
        'fixingPrices': [],
        'observerPrices': []
      }
    ]
  }
  let calcInstrumentForm = form.data
  let result = props.result
  let json = {
    otcOption: otcOption,
    calcInstrumentForm: calcInstrumentForm,
    calcPricingForm: calcPriceParam,
    calcResultForm: result
  }
  return json;
}

// 区间累计：反算区间内收益、区间外收益、区间上限、区间下限；
//反算逻辑
const calcInvert = () => {
  let json = convertJson();
  let {newNpv, yearnpvPercentage, npvPercentage, showSwitch} = proxy.$refs.resultCompRef.getData();
  if (showSwitch) {
    if (isVoid(yearnpvPercentage)) {
      proxy.$modal.msgWarning("请填入npv%");
      return;
    }
  } else {
    if (isVoid(npvPercentage)) {
      proxy.$modal.msgWarning("请填入npv%");
      return;
    }
  }
  json.otcOption.calcPricingParam["marketNPV"] = form.data.notional * npvPercentage / 100;
    let rangeArr = proxy.lsh.cloneDeep(form.data.sections).map((item,index) => {
    return {
      "payoffRate": item.payOffRate / 100,
      "floorPrice": Boolean(item.floorPrice) ? item.floorPrice : '0',
      "capPrice": (form.data.sections.length-1 != index) ? item.capPrice : max
    }
  })
  let capPrices = rangeArr  .map(item => item.capPrice )
  let floorPrices = rangeArr.map(item => item.floorPrice )
  let payoffRates = rangeArr.map(item => item.payoffRate )

  let capPriceZeros = rangeArr  .map(item => item.capPrice ) .filter(item => Number(item) == 0)
  let floorPriceZeros = rangeArr.map(item => item.floorPrice ).filter(item => Number(item) == 0)
  let payoffRateZeros = rangeArr.map(item => item.payoffRate ).filter(item => Number(item) == 0)
  let eleArr = [capPriceZeros.length, Number(floorPriceZeros.length == 2&&(capPriceZeros.length==0)), payoffRateZeros.length];
  let noZeroItems = eleArr.filter(item => Number(item) != 0).length
  /*不能超过1个0*/
 if (noZeroItems != 1) {
    if (noZeroItems == 3) {
      proxy.$modal.msgWarning("请空出反算要素");
      return;
    }else if(payoffRates.indexOf(0) == 0&&payoffRates.lastIndexOf(0)==payoffRates.length-1){

    }
    else {
      proxy.$modal.msgWarning("请填入适当反算要素");
      return;
    }
  }
  //反算区间内收益
  if (payoffRateZeros.length == 1) {
    let rangeIndex = payoffRates.indexOf(0)
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.RANGE_PAYOFF,
          "index": rangeIndex
        }
      ]
    }
    calcContractParamProxy(json.otcOption).then((result) => {
      let amounts = result.amounts.double;
      let ratios = result.ratios.double;
      if (amounts.length > 1) {
        //todo 多个返回值时舍去值的逻辑

      }
      let amountsTarget = amounts[0];
      let ratiosTarget = ratios[0];

      dialogVisible.value = true
      form.data.sections[rangeIndex].payOffRate = ratiosTarget * 100
      if (form.data.sections.length==3){
        Dialog.type = "payOffRate"
        form.data.singleSection.payOffRate = ratiosTarget * 100
        onBlurPayOffRate()
      }
      proxy.$modal.msgSuccess("计算成功！");
    })

  }

  // 区间外收益
  if (payoffRateZeros.length == 2){
    let rangeIndex = payoffRates.indexOf(0)
    let rangeLastIndex = payoffRates.lastIndexOf(0)
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.RANGE_PAYOFF,
          "index": rangeIndex
        } ,{
          "computeType": computeType.RANGE_PAYOFF,
          "index": rangeLastIndex
        }
      ]
    }
    calcContractParamProxy(json.otcOption).then((result) => {
      let amounts = result.amounts.double;
      let ratios = result.ratios.double;
      if (amounts.length > 1) {
        //todo 多个返回值时舍去值的逻辑

      }
      let amountsTarget = amounts[0];
      let ratiosTarget = ratios[0];

      dialogVisible.value = true
      form.data.sections[rangeIndex].payOffRate = ratiosTarget * 100
      form.data.sections[rangeLastIndex].payOffRate = ratiosTarget * 100
      if (form.data.sections.length==3){
        Dialog.type = "outPayOffRate"
        form.data.singleSection.outPayOffRate = ratiosTarget * 100
        onBlurOutPayOffRate()
      }
      proxy.$modal.msgSuccess("计算成功！");
    })
  }
  // 区间上限
  if (capPriceZeros.length == 1&&capPrices.lastIndexOf(0) != 0){
    let rangeIndex = capPrices.indexOf(0)
    let rangeLastIndex = rangeIndex + 1
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.CAP_PRICE,
          "index": rangeIndex
        },{
          "computeType": computeType.FLOOR_PRICE,
          "index": rangeLastIndex
        }
      ]
    }
    json.otcOption["sectionSolvers"] =
        {"cap":2* rangeArr[rangeLastIndex].capPrice,"floor":rangeArr[rangeIndex].floorPrice,"step":2}
    calcContractParamProxy(json.otcOption).then((result) => {
      let amounts = result.amounts.double;
      let ratios = result.ratios.double;
      if (amounts.length > 1) {
        //todo 多个返回值时舍去值的逻辑

      }
      let amountsTarget = amounts[0];
      let ratiosTarget = ratios[0];

      dialogVisible.value = true
      form.data.sections[rangeIndex].capRate = ratiosTarget * 100
      form.data.sections[rangeLastIndex].floorRate = ratiosTarget * 100
      if (form.data.sections.length==3){
        Dialog.type = "capRate"
        form.data.singleSection.capRate = ratiosTarget * 100
        onBlurCapRate()
      }
      proxy.$modal.msgSuccess("计算成功！");
    })
  }
  // 区间下限
  /*反算上限时，不反算下限*/
  if (floorPriceZeros.length == 2&&capPrices.lastIndexOf(0) == 0){
    let rangeIndex = floorPrices.indexOf('0')
    let rangeLastIndex = floorPrices.lastIndexOf('0')
    json.otcOption["contractRoots"] = {
      "contractRoot": [
        {
          "computeType": computeType.CAP_PRICE,
          "index": rangeIndex
        },{
          "computeType": computeType.FLOOR_PRICE,
          "index": rangeLastIndex
        }
      ]
    }
    json.otcOption["sectionSolvers"] =
        {"cap":2* rangeArr[rangeLastIndex].capPrice,"floor":0.01*form.data.spotPrice,"step":2}
    calcContractParamProxy(json.otcOption).then((result) => {
      let amounts = result.amounts.double;
      let ratios = result.ratios.double;
      if (amounts.length > 1) {
        //todo 多个返回值时舍去值的逻辑

      }
      let amountsTarget = amounts[0];
      let ratiosTarget = ratios[0];

      dialogVisible.value = true
      form.data.sections[rangeIndex].capRate = ratiosTarget * 100
      form.data.sections[rangeLastIndex].floorRate = ratiosTarget * 100
      if (form.data.sections.length==3){
        Dialog.type="floorRate"
        form.data.singleSection.floorRate = ratiosTarget * 100
        onBlurFloorRate()
      }
      proxy.$modal.msgSuccess("计算成功！");
    })
  }
}
// 区间上下限校验逻辑
const validateCapAndFloor = (dataItem) => {
  if (form.data.priceOnWait == '1'){
    if(
        (Number(dataItem.capRate) ==0 && Number(dataItem.floorPrice) ==0 )
        ||
        (Number(dataItem.floorRate) ==0 && Number(dataItem.capPrice) ==0 )

    ){
      proxy.$modal.alertWarning('期初价格待定情况下,输入区间上限和区间下限时。请仅使用比例或仅使用金额!')
      throw new Error('期初价格待定情况下,输入区间上限和区间下限时。请仅使用比例或仅使用金额!')
    }
  }
  if (
      (Number(dataItem.capRate) <= Number(dataItem.floorRate))
      &&
      (Number(dataItem.capPrice) <= Number(dataItem.floorPrice))
  ) {
    proxy.$modal.alertWarning('区间上限必须大于区间下限,请核对!')
    throw  new Error('区间上限必须大于区间下限,请核对!')
  }
}

const getInstrumentJson = async () => {
  return new Promise((resolve) => {
    //单区间时的校验逻辑
    if (!form.data.singleSectionHidden){
      validateCapAndFloor(form.data.singleSection)
    }else {
      //多区间时的校验逻辑
      for (let formElement of form.data.sections) {
        validateCapAndFloor(formElement)
      }
    }
    /*若form.data.startDate为空，initStratAndEndDates*/
    if (isVoid(form.data.startDate)) {
      initStratAndEndDates()
    }
    proxy.$refs['formRef'].validate(valid => {
      if (valid) {
        validateDates(form)
        let json = convertJson();
        resolve(json)
      } else {
        resolve('')
      }
    })
  })
}
const calc = (flag) => {
  /*flag 标识 为All时单次计算不会提示成功或失败*/
  getInstrumentJson().then((res) => {
    if (Boolean(res)) {
      let otcOption = res.otcOption
      otcOption.calcInstrumentForm = res.calcInstrumentForm
      otcOption.calcPricingForm = res.calcPricingForm
      if (otcOption != '') {
        props.calc(otcOption, props.index, flag)
      }
    }
  })
}
const save2Trade = () => {
  getInstrumentJson().then((res) => {
    if (Boolean(res)) {
      props.save2Trade(res, props.index)
    }
  })

}
const save2CalcLog = () => {
  getInstrumentJson().then((res) => {
    if (Boolean(res)) props.save2CalcLog(res, props.index)
  })

}
const getCalcPriceParam = () => {
  let calcPriceParam = proxy.$refs.PricingParamRef.getCalcPricingParam()
  return calcPriceParam
}
const getFormData = () => {
  return form
}

defineExpose({
  calc, getPricingCfg, getCalcPriceParam, getFormData, save2Trade, save2CalcLog, getInstrumentJson,proxy
})
onMounted(() => {
  /*获取默认定价配置*/
  // getPricingCfg()
  /*获取预填表单*/
  form.initFlag = props.isReCalc
  if (props.formData != null) {
    let data = props.formData.data || props.formData
    form.data = Object.assign(form.data, data)
    form.initFlag = isNotVoid(props.calcPricingParam)
  }
  console.log(form)
  // 这里获取DOM的value是旧值
  nextTick(()=>{
    form.initFlag = false
  })
})

/*计息区间*/
const xToolbar = ref({})
const xTable = ref({})
const Calendars = reactive({
  datesArr: [],
  dates: []
})


const rangeDialog = reactive({
  loading: false,
  validRules: {
    name: [
      {required: true, message: '名称必须填写'}
    ]
  }
})

const insertEvent = async () => {
  const $table = xTable.value
  const newRecord = {}
  const {row: newRow} = await $table.insert(newRecord)
  await $table.setActiveRow(newRow)
}

const removeSelectEvent = async () => {
  const $table = xTable.value
  await $table.removeCheckboxRow()
}

const reloadRowEvent = async () => {
  if (form.initFlag) return
  form.data.sections = proxy.lsh.cloneDeep(defaultSections.data)
  form.data.singleSectionHidden = false
}


const removeRowEvent = async (row) => {
  const $table = xTable.value
  const checkboxRecords = $table.getCheckboxRecords()
  // let sectionsArr =  form.data.sections.map(item=>item._X_ROW_KEY)
  checkboxRecords.forEach(item => {
    let key = item._X_ROW_KEY
    // let current = sectionsArr.indexOf(key)
    // form.data.sections.splice(current, 1)
    // form.data.sections.splice(current, 1)
    form.data.sections = form.data.sections.filter(a => {
      return a._X_ROW_KEY != item._X_ROW_KEY
    })
  })

}

const saveEvent = async () => {
  const $table = xTable.value
  const {insertRecords, removeRecords, updateRecords} = $table.getRecordset()
  if (insertRecords.length <= 0 && removeRecords.length <= 0 && updateRecords.length <= 0) {
    // VXETable.modal.message({content: '数据未改动！', status: 'warning'})
    // proxy.$modal.notify('数据未改动！')
    // return
  } else {
    form.data.singleSectionHidden = true
  }
  // const errMap = await $table.validate()
  // if (errMap) {
  //   return
  // }
  /*
  * {
    "floorPrice": 0,
    "floorRate": 0,
    "capPrice": 0,
    "capRate": 0,
    "payOffRate": 0,
    "isIncludeCap": "1",
    "isIncludeFloor": "1",
    "_X_ROW_KEY": "row_33"
}
  * */
  // sectionOverlap  insertRecords
  //判断下限小于上限和区间是否重叠
  var floorFlag = false
  var list = []
  $table.getTableData().tableData.some(element => {
    if (element.floorPrice > element.capPrice) {
      if (element.capPrice != '') {
        proxy.$modal.notify('行权下限必须小于上限')
        floorFlag = true
        return true
      }
    } else if (element.floorPrice == element.capPrice) {
      proxy.$modal.notify('行权下限必须小于上限')
      floorFlag = true
      return true
    }
    list.push({min: element.floorPrice, max: element.capPrice})
  })

  if (floorFlag == true || sectionOver(list) == true) {
    return
  }

  proxy.$modal.notify('数据保存成功！')
  //  置灰外部的区间输入
  form.data.sections = $table.getTableData().tableData
  dialogVisible.value = false
}

function sectionOver(list) {
  var flag = false
  if (list.length > 1) {
    list.some(item => {
      list.some(subItem => {
        if (subItem.min < item.min && item.min < subItem.max) {
          // 分别把开始和结束，放入区间内比较
          proxy.$modal.notify('区间存在重叠交叉！重叠数据为：' + item.min)
          flag = true
          return true
        } else if (subItem.min < item.max && item.max < subItem.max) {
          proxy.$modal.notify('区间存在重叠交叉！重叠数据为：' + subItem.min)
          flag = true
          return true
        }
      })
      if (flag === true) {
        return true
      }
    })
  }
  return flag
}

/*设置默认的观察日期*/
function initStratAndEndDates() {
  if (isVoid(form.data.startDate)) {
    form.data.startDate = proxy.$moment(form.data.effectiveDate).format('YYYY-MM-DD')
  }
  if (isVoid(form.data.endDate)) {
    form.data.endDate = proxy.$moment(form.data.terminationDate).format('YYYY-MM-DD')
  }
}

/*观察日期列表*/
const openObservation = () => {
  ObservationVisible.value = true
  initStratAndEndDates();
  generateData()
}
const handleEdit = (index, row) => {
  row.flag = 'r'
}
const handleDelete = (index, row) => {
  row.flag = 'l'
}
const EditCalendars = (value) => {
  Calendars.dates.forEach(item => {
    item.flag = value
  })
}
const generateData = async () => {
  let param = {
    startDay: proxy.$moment(form.data.effectiveDate).format('YYYY-MM-DD'),
    endDay: proxy.$moment(form.data.terminationDate).format('YYYY-MM-DD')
  }
  getCalendar(param).then(response => {
        if (response.errorCode != 0) {
          proxy.$modal.msgError('出错！\n' + response.errorMsg)
        } else {
          Calendars.datesArr = response.result.map(item => item.CAL_DAY)
          Calendars.dates = response.result.map(item => (
              {
                date: item.CAL_DAY,
                flag: 'l'
              }
          ))
        }
      }
  )
}

watch(() => [form.data.startDate, form.data.endDate], () => {
  generateData()
  proxy.$refs.PricingParamRef?proxy.$refs.PricingParamRef.calcRateByCode():''
})


const getLeftDates = () => {
  return Calendars.dates.filter((item) => item.flag == 'l')
}
const getRightDates = () => {
  return Calendars.dates.filter((item) => item.flag == 'r')
}
const disabledDate = (time) => {
  // return !Calendars.datesArr.includes(proxy.$moment(time).format('YYYY-MM-DD'))

  return !(proxy.$moment(time).isAfter(form.data.effectiveDate) && proxy.$moment(time).isBefore(form.data.terminationDate))
}
const saveObservations = () => {
  form.data.discreteDates = Calendars.dates.filter((item) => item.flag == 'r').map(item => item.date)
  ObservationVisible.value = false
}
const onBlurOutPayOffRate = () => {
  if (form.data.moneynessOption == '1') {
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    form.data.singleSection.outPayOffPrice = proxy.lsh.round(proxy.lsh.divide(proxy.lsh.multiply(proxy.lsh.multiply(form.data.singleSection.outPayOffRate,annualized),form.data.notional),100),2)

  }else {
    form.data.singleSection.outPayOffPrice = proxy.lsh.round(proxy.lsh.divide(proxy.lsh.multiply(form.data.singleSection.outPayOffRate,form.data.notional),100),2)

  }
}
const onBlurOutPayOffPrice = () => {
  if (form.data.moneynessOption == '1') {
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    form.data.singleSection.outPayOffRate = proxy.lsh.round(
        proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.divide(form.data.singleSection.outPayOffPrice,form.data.notional),annualized),100),2
    )
  }else {
    form.data.singleSection.outPayOffRate = proxy.lsh.round(
        proxy.lsh.multiply(proxy.lsh.divide(form.data.singleSection.outPayOffPrice,form.data.notional),100),2)
  }

}
watch(() => [form.data.moneynessOption], ([newValue], [oldValue]) => {
    onBlurOutPayOffRate()
    onBlurPayOffRate()
})
const onBlurPayOffRate = () => {
  if (form.data.moneynessOption == '1') {
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    form.data.singleSection.payOffPrice = proxy.lsh.round(proxy.lsh.divide(proxy.lsh.multiply(proxy.lsh.multiply(form.data.singleSection.payOffRate,annualized),form.data.notional),100),2)

  }else {
    form.data.singleSection.payOffPrice = proxy.lsh.round(proxy.lsh.divide(proxy.lsh.multiply(form.data.singleSection.payOffRate,form.data.notional),100),2)

  }

}
const onBlurPayOffPrice = () => {
  if (form.data.moneynessOption == '1') {
    let annualized = calcAnnualizedByTerminationPaymentDate(form.data)
    form.data.singleSection.payOffRate = proxy.lsh.round(
            proxy.lsh.multiply(proxy.lsh.divide(proxy.lsh.divide(form.data.singleSection.payOffPrice,form.data.notional),annualized),100),2
        )
  }else {
    form.data.singleSection.payOffRate = proxy.lsh.round(
        proxy.lsh.multiply(proxy.lsh.divide(form.data.singleSection.payOffPrice,form.data.notional),100),2)
  }

}
watch(()=>form,()=>{

  proxy.$attrs.cacheFormData()
},{deep:true})
</script>
<style scoped>
.dialog-footer button:first-child {
  margin-right: 10px;
}

/deep/ .el-dialog__header {
  text-align: left;
}
/deep/ .optionst02 .optionst02_d .el-input.is-disabled .el-input__inner {
  background-color: var(--el-disabled-bg-color);
  color: #ffffff !important;
  text-decoration: line-through;
  cursor: not-allowed;
}
</style>

